﻿using black_screen_mode_server.DataCommunication;
using black_screen_mode_server.Models;
using black_screen_mode_server.Pages;
using DocumentFormat.OpenXml.Office.Excel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;


namespace black_screen_mode_server
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private TcpServerHelper tcpServer;
        private TimedFormPage timePg = new TimedFormPage();
        private ParametesSetupPage parametesSetupPage = new ParametesSetupPage();
        private MonitoringPage monitoringPage = new MonitoringPage();
        private DatabasePage databasePage = new DatabasePage();
        private Dictionary<int, string> dicCategoryDesc = new Dictionary<int, string>();
        private string iniFilePath = "./Assets/IniSettings.ini";
        public MainWindow(string userName)
        {
            #region 测试代码
            //DateTime test = DateTime.Now;
            //string revert = ProjectTools.ConvertToPhdTime(test);
            //DateTime test1 = DateTime.Now.AddMinutes(5);
            //string revert1 = ProjectTools.ConvertToPhdTime(test1);
            #endregion

            InitializeComponent();
            this.MyNotifyIcon.ToolTipText = string.IsNullOrEmpty(ProjectTools.getParamInfos().serverName.Trim()) ? "黑屏模式服务端" : ProjectTools.getParamInfos().serverName.Trim();
            MainFrame.Navigate(timePg);

            //
            //{ 1, "Process Alarm"},
            //{ 3, "System Alarm"},
            //{ 4, "Information Message"},
            //{ 7, "Operator Change"},
            //{ 8, "System Change"},
            //{ 9, "Sequence of Events"},
            //{ 11, "Confirmation Message"},
            //{ 12, "Process Event"},
            //{ 14, "System Event"},
            //{ 17, "Process Alert"},
            //{ 18, "Simple Alert"},
            //{ 20, "Batch Event"},
            //{ 21, "Procedure Event"},
            //{ 24, "Batch Tracking Event"}
            //
            this.dicCategoryDesc.Add(1, "process alarm");
            this.dicCategoryDesc.Add(3, "System Alarm");
            this.dicCategoryDesc.Add(4, "Information Message");
            this.dicCategoryDesc.Add(7, "Operator Change");
            this.dicCategoryDesc.Add(8, "System Change");
            this.dicCategoryDesc.Add(9, "Sequence of Events");
            this.dicCategoryDesc.Add(11, "Confirmation Message");
            this.dicCategoryDesc.Add(12, "Process Event");
            this.dicCategoryDesc.Add(14, "System Event");
            this.dicCategoryDesc.Add(17, "Process Alert");
            this.dicCategoryDesc.Add(18, "Simple Alert");
            this.dicCategoryDesc.Add(20, "Batch Event");
            this.dicCategoryDesc.Add(21, "Procedure Event");
            this.dicCategoryDesc.Add(24, "Batch Tracking Event");
            txtAccount.Text = userName;
            initDataProcess();

            // 创建TCP 服务
            tcpServer = new TcpServerHelper(ProjectTools.getTcpServer().IpAddress, ProjectTools.getTcpServer().PortNumber);
            tcpServer.SocketReceive += DataCommunicationMng.GetInstance().DataReceive;
            tcpServer.SocketMessage += NormalInfo;
            JudgeAccount(userName);

        }

        public void setDefaultView()
        {
            this.MainFrame.Navigate(timePg);
        }

        public void setUserName(string name)
        {
            this.txtAccount.Text = name;
        }

        private void NormalInfo(string msg, Exception ex, Socket s)
        {
            if (ex != null)
                Logger.Singleton.Error(msg, ex);
            else
                Logger.Singleton.Info(msg);
        }

        //private void ErroInfo(string msg, Exception ex, Socket s)
        //{
        //    Logger.Singleton.Error(msg, ex);

        //}


        //数据处理初始化
        private void initDataProcess()
        {
            DataCommunicationMng.GetInstance().RegisterDataProcess(DataPacketType.GroupRequest, GroupRequestDataProcess);
            DataCommunicationMng.GetInstance().RegisterDataProcess(DataPacketType.RegisterRequest, RegisterRequestDataProcess);
            DataCommunicationMng.GetInstance().RegisterDataProcess(DataPacketType.LogRequest, LogRequestDataProcess);
            DataCommunicationMng.GetInstance().RegisterDataProcess(DataPacketType.CancelRegister, CancelRegisterDataProcess);
            DataCommunicationMng.GetInstance().RegisterDataProcess(DataPacketType.HeartRequest, HeartBeatDataProcess);
        }

        private void SetServerStatus(bool status)
        {
            if (DataCommunicationMng.GetInstance().SetServerRunFlag(status))
            {
                if (status)
                {
                    //启动服务
                    tcpServer.start();
                    PksEventMonitoring();
                    timePg.StartFunctions();

                    //服务启动，禁用设置
                    //this.parametesSetupPage.btnParameterConfirm.IsEnabled = false;
                    //this.monitoringPage.btnImportWhiteList.IsEnabled = false;
                    //this.monitoringPage.btnGroupSetting.IsEnabled = false;
                    //this.monitoringPage.btnFindTag.IsEnabled = false;
                    //this.databasePage.btnDatabaseConfirm.IsEnabled = false;
                    //this.timePg.btnFormConfirm.IsEnabled = false;
                    AccessControl(true, false, false, false, true);


                }
                else
                {
                    //停止服务
                    DataCommunicationMng.GetInstance().RemoveAllClient();
                    DataCommunicationMng.GetInstance().removeAllGroupScreenInfos();
                    DataCommunicationMng.GetInstance().SetServerRunFlag(false);
                    tcpServer.stop();
                    timePg.StopFunctions();
                    databasePage.Stop();

                    //this.parametesSetupPage.btnParameterConfirm.IsEnabled = true;
                    //this.monitoringPage.btnImportWhiteList.IsEnabled = true;
                    //this.monitoringPage.btnGroupSetting.IsEnabled = true;
                    //this.monitoringPage.btnFindTag.IsEnabled = true;
                    //this.databasePage.btnDatabaseConfirm.IsEnabled = true;
                    //this.timePg.btnFormConfirm.IsEnabled = true;
                    AccessControl(true, true, true, true, true);

                }
            }
        }
        private void LogRequestDataProcess(DataPacketType type, string data, Socket src)
        {
            LogRequestData logRequestData = new LogRequestData();
            logRequestData.JsonToPacket(data);
            //查询数据库，获取当前分组的所有点位值
            //SqlHelper sqlHelper = new SqlHelper(ProjectTools.configDbConnString);
            //string sql = $"select tag from black_list where group_id = {logRequestData.GroupId}";
            //DataTable dt = sqlHelper.GetByTable(sql);
            //List<string> tags = new List<string>();
            //if (dt != null && dt.Rows.Count > 0)
            //{
            //    for (int i = 0; i < dt.Rows.Count; i++)
            //    {
            //        tags.Add(dt.Rows[i]["tag"].ToString());
            //    }
            //}
            //string tagStr = "";
            //foreach (var tag in tags)
            //{
            //    tagStr += $"'{tag}',";
            //}
            //获取组名
            SqlHelper sqlHelper = new SqlHelper(ProjectTools.configDbConnString);
            string sqlQueryGroupName = $"select Name from [group] where id = {logRequestData.GroupId}";
            DataTable dtGroupName = sqlHelper.GetByTable(sqlQueryGroupName);
            string groupName = "";
            if (dtGroupName != null && dtGroupName.Rows.Count > 0)
            {
                groupName = dtGroupName.Rows[0]["Name"].ToString();
            }

            List<EventDataModel> eventModels = new List<EventDataModel>();

            string sqlQuery = $"select top(10) [source],[location_tag_name],[area_code],[source_sort],[priority],[category],[description],[end_time],[condition_name] from [dbo].[timing_report] where groupName='{groupName}' order by [end_time] desc";
            DataTable dt = sqlHelper.GetByTable(sqlQuery);
            //if (dt != null && dt.Rows.Count > 0)
            //{
            //    for (int i = 0; i < dt.Rows.Count; i++)
            //    {
            //        EventDataModel eventDataModel = new EventDataModel();
            //        eventDataModel.CurGroupName = groupName;
            //        eventDataModel.ConditionName = dt.Rows[i]["condition_name"].ToString();
            //        if (dicCategoryDesc.ContainsKey(Convert.ToInt32(dt.Rows[i]["category"])))
            //            eventDataModel.CategoryName = dicCategoryDesc[Convert.ToInt32(dt.Rows[i]["category"])];
            //        eventDataModel.Description = dt.Rows[i]["description"].ToString();
            //        eventDataModel.Priority = dt.Rows[i]["priority"].ToString();
            //        //将end_time时间字段转为DateTime类型
            //        eventDataModel.LocalTime = Convert.ToDateTime(dt.Rows[i]["end_time"].ToString());
            //        eventDataModel.SourceEntityName = dt.Rows[i]["source_sort"].ToString();
            //        eventDataModel.Category = Convert.ToInt32(dt.Rows[i]["category"]);
            //        eventDataModel.AreaCode = Convert.ToInt32(dt.Rows[i]["area_code"]);
            //        eventDataModel.Source = dt.Rows[i]["source"].ToString();
            //        eventDataModel.LocationTagName = dt.Rows[i]["location_tag_name"].ToString();
            //        eventModels.Add(eventDataModel);
            //    }
            //}
            if (dt != null && dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    var row = dt.Rows[i];
                    EventDataModel eventDataModel = new EventDataModel();

                    // 辅助方法：安全获取字符串（处理 null / DBNull）
                    string SafeGetString(string colName)
                    {
                        var val = row[colName];
                        return val == null || val == DBNull.Value ? string.Empty : val.ToString().Trim();
                    }

                    // 辅助方法：安全转整数
                    int SafeGetInt(string colName, int defaultValue = 0)
                    {
                        var val = row[colName];
                        if (val == null || val == DBNull.Value) return defaultValue;
                        if (int.TryParse(val.ToString(), out int result))
                            return result;
                        Logger.Singleton.Warn($"无法解析整数字段 '{colName}'，值为 '{val}'，使用默认值 {defaultValue}");
                        return defaultValue;
                    }

                    // 辅助方法：安全转 DateTime
                    DateTime? SafeGetDateTime(string colName)
                    {
                        var val = row[colName];
                        if (val == null || val == DBNull.Value) return null;
                        if (DateTime.TryParse(val.ToString(), out DateTime dtResult))
                            return dtResult;
                        Logger.Singleton.Warn($"无法解析时间字段 '{colName}'，值为 '{val}'");
                        return null;
                    }

                    try
                    {
                        eventDataModel.CurGroupName = groupName ?? string.Empty;
                        eventDataModel.ConditionName = SafeGetString("condition_name");
                        eventDataModel.Description = SafeGetString("description");
                        eventDataModel.Priority = SafeGetString("priority");
                        eventDataModel.SourceEntityName = SafeGetString("source_sort");
                        eventDataModel.Source = SafeGetString("source");
                        eventDataModel.LocationTagName = SafeGetString("location_tag_name");

                        // 整数字段
                        eventDataModel.Category = SafeGetInt("category");
                        eventDataModel.AreaCode = SafeGetInt("area_code");

                        // 时间字段（可为空）
                        var localTime = SafeGetDateTime("end_time");
                        eventDataModel.LocalTime = localTime ?? DateTime.MinValue; // 或根据业务决定默认值，如 DateTime.Now

                        // CategoryName 映射
                        if (dicCategoryDesc != null && dicCategoryDesc.ContainsKey(eventDataModel.Category))
                        {
                            eventDataModel.CategoryName = dicCategoryDesc[eventDataModel.Category];
                        }
                        else
                        {
                            eventDataModel.CategoryName = "未知";
                            if (eventDataModel.Category != 0) // 避免默认0也报未知
                            {
                                Logger.Singleton.Warn($"Category {eventDataModel.Category} 未在 dicCategoryDesc 中定义");
                            }
                        }

                        eventModels.Add(eventDataModel);
                    }
                    catch (Exception ex)
                    {
                        Logger.Singleton.Error($"处理第 {i} 行数据时发生异常: {ex.Message}", ex);
                        // 可选择跳过该行，或添加默认对象，根据业务需求
                        // 这里选择跳过（不 add），避免脏数据
                    }
                }
            }

            ////去掉最后一个逗号
            //if (tagStr.Length != 0)
            //{
            //    tagStr = tagStr.Substring(0, tagStr.Length - 1);
            //    string sqlQueryEvents = $"select top(10) [Source],[LocationTagName],[AreaCode],[SourceEntityName],[Priority] ,[Category] ,[Description] , [LocalTime],[ConditionName] from [emsevents].[dbo].[Events] where Category in (1, 3, 7) and [Action]!='OK' and [Source] in ({tagStr}) order by LocalTime desc";
            //    SqlHelper eventSqlHelper1 = new SqlHelper(ProjectTools.eventDbConnectionModel.Conn1);
            //    SqlHelper eventSqlHelper2 = new SqlHelper(ProjectTools.eventDbConnectionModel.Conn2);
            //    DataTable dtEvents = new DataTable();
            //    try
            //    {
            //        dtEvents = eventSqlHelper1.GetByTable(sqlQueryEvents);
            //    }
            //    catch (Exception)
            //    {
            //        dtEvents = eventSqlHelper2.GetByTable(sqlQueryEvents);
            //    }
            //    //读取dtEvents，组装EventDataModel
            //    if (dtEvents != null && dtEvents.Rows.Count > 0)
            //    {
            //        for (int i = 0; i < dtEvents.Rows.Count; i++)
            //        {
            //            EventDataModel eventDataModel = new EventDataModel();
            //            eventDataModel.CurGroupName = groupName;
            //            eventDataModel.ConditionName = dtEvents.Rows[i]["ConditionName"].ToString();
            //            if (dicCategoryDesc.ContainsKey(Convert.ToInt32(dtEvents.Rows[i]["Category"])))
            //                eventDataModel.CategoryName = dicCategoryDesc[Convert.ToInt32(dtEvents.Rows[i]["Category"])];
            //            eventDataModel.Description = dtEvents.Rows[i]["Description"].ToString();
            //            eventDataModel.Priority = Convert.ToInt32(dtEvents.Rows[i]["Priority"]);
            //            DateTime tmp = new DateTime();
            //            ProjectTools.ConvertActiveTime(dtEvents.Rows[i]["LocalTime"].ToString().Trim(), out tmp);
            //            eventDataModel.LocalTime = tmp;
            //            eventDataModel.SourceEntityName = dtEvents.Rows[i]["SourceEntityName"].ToString();
            //            eventDataModel.Category = Convert.ToInt32(dtEvents.Rows[i]["Category"]);
            //            eventDataModel.AreaCode = Convert.ToInt32(dtEvents.Rows[i]["AreaCode"]);
            //            eventDataModel.Source = dtEvents.Rows[i]["Source"].ToString();
            //            eventDataModel.LocationTagName = dtEvents.Rows[i]["LocationTagName"].ToString();
            //            eventModels.Add(eventDataModel);
            //        }
            //    }
            //}

            //组装数据包
            LogResponseData logResponseData = new LogResponseData();
            logResponseData.LogData = eventModels;
            string response = logResponseData.PacketToJson();
            DataPacket dpResponse = new DataPacket();
            dpResponse.PacketType = (int)DataPacketType.LogResponse;
            dpResponse.PacketData = response;
            src.Send(Encoding.UTF8.GetBytes(dpResponse.PacketToJson()));

        }

        private void RegisterRequestDataProcess(DataPacketType type, string data, Socket src)
        {
            RegisterRequestData registerRequestData = new RegisterRequestData();
            registerRequestData.JsonToPacket(data);
            DataCommunicationMng.GetInstance().RegisterClient(registerRequestData.GroupId, src);
        }

        private void GroupRequestDataProcess(DataPacketType type, string data, Socket src)
        {
            //查询数据库，获取分组信息
            SqlHelper sqlHelper = new SqlHelper(ProjectTools.configDbConnString);
            DataTable dt = sqlHelper.GetByTable("select * from [group]");
            List<GroupInfoModel> groupInfos = new List<GroupInfoModel>();
            if (dt != null && dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    GroupInfoModel groupInfo = new GroupInfoModel();
                    groupInfo.Id = Convert.ToInt32(dt.Rows[i]["id"]);
                    groupInfo.Name = dt.Rows[i]["Name"].ToString();
                    groupInfos.Add(groupInfo);
                }
            }
            //组装数据包
            GroupResponseData groupResponseData = new GroupResponseData();
            groupResponseData.GroupInfos = groupInfos;
            string response = groupResponseData.PacketToJson();
            DataPacket dpResponse = new DataPacket();
            dpResponse.PacketType = (int)DataPacketType.GroupResponse;
            dpResponse.PacketData = response;
            src.Send(Encoding.UTF8.GetBytes(dpResponse.PacketToJson()));
        }

        private void CancelRegisterDataProcess(DataPacketType type, string data, Socket src)
        {
            CancelRegisterData cancelRegisterData = new CancelRegisterData();
            cancelRegisterData.JsonToPacket(data);
            DataCommunicationMng.GetInstance().RemoveClient(src);
        }

        private void HeartBeatDataProcess(DataPacketType type, string data, Socket src)
        {
            HeartRequestData heartIn = new HeartRequestData();
            heartIn.JsonToPacket(data);
            DataPacket rp = new DataPacket();
            rp.PacketType = (int)DataPacketType.HeartResponse;
            HeartResponseData heartRp = new HeartResponseData();
            heartRp.clientId = heartIn.clientId;
            rp.PacketData = heartRp.PacketToJson();
            src.Send(Encoding.UTF8.GetBytes(rp.PacketToJson()));
        }

        //权限设置
        public void JudgeAccount(string userName)
        {
            if (userName != "admin" && userName != "admin")
            {
                AccessControl(true, false, false, false, false);

            }
            else
            {
                AccessControl(true, true, true, true, true);
            }
        }

        private void AccessControl(bool canSetTimer, bool canSetParmas, bool canSetDatabase, bool canSetMoniter, bool canStartService)
        {

            this.btnTimedTask.IsEnabled = canSetTimer ? true : false;
            this.btnParameters.IsEnabled = canSetParmas ? true : false;
            this.btnMonitor.IsEnabled = canSetMoniter ? true : false;
            this.btnDatabaseSetup.IsEnabled = canSetDatabase ? true : false;

            this.timePg.IsEnabled = canSetTimer ? true : false;
            this.parametesSetupPage.IsEnabled = canSetParmas ? true : false;
            this.monitoringPage.IsEnabled = canSetMoniter ? true : false;
            this.databasePage.IsEnabled = canSetDatabase ? true : false;

            this.btnServerStart.IsEnabled = canStartService ? true : false;
            this.btnServerStart.Visibility = canStartService ? Visibility.Visible : Visibility.Hidden;

        }

        //注销
        private void btnLogoff_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = System.Windows.MessageBox.Show("确认注销当前账号？", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question);

            if (result == MessageBoxResult.Yes)
            {
                LoginWindow loginWindow = new LoginWindow();
                loginWindow.Show();
                this.Close();
            }
        }

        //页面切换--参数设置
        private void btnParameters_Click(object sender, RoutedEventArgs e)
        {
            MainFrame.Content = this.parametesSetupPage;
        }

        //页面切换--位号监控
        private void btnMonitor_Click(object sender, RoutedEventArgs e)
        {
            MainFrame.Content = this.monitoringPage;
        }

        //页面切换--定时报表
        private void btnTimedTask_Click(object sender, RoutedEventArgs e)
        {
            MainFrame.Content = this.timePg;
        }

        //页面切换--数据库设置
        private void btnDatabaseSetup_Click(object sender, RoutedEventArgs e)
        {
            MainFrame.Content = this.databasePage;
        }

        //最小化托盘
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
            this.Visibility = Visibility.Collapsed;

        }

        //打开主界面
        private void ShowMainWindow_Click(object sender, RoutedEventArgs e)
        {
            if (!(this is LoginWindow))
            {
                foreach (Window window in System.Windows.Application.Current.Windows)
                {
                    if (window is LoginWindow)
                    {
                        window.Close();
                    }
                }
                this.Visibility = Visibility.Visible;
            }
        }

        //双击显示主界面
        private void MyNotifyIcon_TrayMouseDoubleClick(object sender, RoutedEventArgs e)
        {
            bool isFindLogwindows = false;

            foreach (Window window in System.Windows.Application.Current.Windows)
            {
                if (window is LoginWindow)
                {
                    isFindLogwindows = true;
                    break;
                }
            }

            if (isFindLogwindows)
            {
                this.Visibility = Visibility.Collapsed;
            }
            else
            {
                this.Visibility = Visibility.Visible;
            }

        }

        //退出程序
        private void Exist_Click(object sender, RoutedEventArgs e)
        {
            SetServerStatus(false);
            System.Windows.Application.Current.Shutdown();
        }



        private async Task PksEventMonitoring()
        {


            //获取appsetting.json中的配置
            ParametersInfo parameters = ProjectTools.getParamInfos();


            // 1.如果最新时间 >= 最近报警时间 + 延迟时间，则当前为黑屏；
            // 2.否则为白屏。

            // 如果为黑屏，黑屏开始时间 = 最近报警时间 + 延迟时间
            // 如果为白屏，白屏开始时间 = 最近报警时间,也为黑屏结束时间
            int currentServerUse = 0;
            bool bServerChange = false;
            SqlHelper[] eventServerArray = new SqlHelper[2];
            eventServerArray[0] = new SqlHelper(ProjectTools.eventDbConnectionModel.Conn1);
            Logger.Singleton.Info("连接1信息："+ ProjectTools.eventDbConnectionModel.Conn1);
            eventServerArray[1] = new SqlHelper(ProjectTools.eventDbConnectionModel.Conn2);
            Logger.Singleton.Info("连接2信息：" + ProjectTools.eventDbConnectionModel.Conn2);
            int userAccess = 0;


            await Task.Run(() =>
            {
                #region 获取分组及配置点位/ 获取黑名单，白名单，筛选出需要监控的点

                //          List<TagGroupModel> TagGroups = new List<TagGroupModel>();

                //          SqlHelper sqlLocal = new SqlHelper(ProjectTools.configDbConnString);
                //          DataTable dtGroup = sqlLocal.GetByTable("select * from group");

                //          DataTable dtBlackList = sqlLocal.GetByTable($"SELECT a.[id] as 'GroupId',a.[Name] as 'GroupName', b.id as 'TagId', b.tag as 'TagName' " +
                //"FROM [group] a left join [black_list] b on a.id = b.group_id where b.id is not null");

                 //         TagGroups = GetTagGroupFromTable(dtGroup, dtBlackList);

                //          foreach (TagGroupModel item in TagGroups)
                //          {
                //              DataCommunicationMng.GetInstance().RegisterGroupScreenInfos(Convert.ToInt32(item.Id), new CurrentGroupScreenInfos(Convert.ToInt32(item.Id)));
                //          }
                SqlHelper sqlHelper = new SqlHelper(ProjectTools.configDbConnString);

                //获取当前工艺/分组信息
                List<GroupInfo> groupInfos = new List<GroupInfo>();
                string groupInfoSql = $"select * from [group]";
                try
                {
                    DataTable groupInfoDt = sqlHelper.GetByTable(groupInfoSql);
                    if (groupInfoDt != null && groupInfoDt.Rows.Count > 0)
                    {
                        for (int i = 0; i < groupInfoDt.Rows.Count; i++)
                        {
                            GroupInfo gp = new GroupInfo();
                            gp.Id = Convert.ToInt32(groupInfoDt.Rows[i]["id"]);
                            gp.Name = groupInfoDt.Rows[i]["Name"].ToString();
                            groupInfos.Add(gp);
                        }
                    }
                }
                catch (Exception)
                {
                    Logger.Singleton.Info("获取分组信息失败！");
                }

                //初始化/注册分组当前信息
                foreach (GroupInfo item in groupInfos)
                {
                    DataCommunicationMng.GetInstance().RegisterGroupScreenInfos(Convert.ToInt32(item.Id), new CurrentGroupScreenInfos(Convert.ToInt32(item.Id)));
                }


                //获取黑白名单
                List<ListInfo> blackList = ListInfoSqlHelper.GetListInfo(0);
                List<ListInfo> whiteList = ListInfoSqlHelper.GetListInfo(1);

                Dictionary<int, string> strSqlConditions = GenConditionSqlPart(blackList, whiteList, groupInfos);
                #endregion
                //各组最近报警时间
                DataTable dataTable = null;


                // 轮询各分组下面的PKS点事件，如果发现-- 1: progress alarm --3: system alarm --7: operator change，则发送消息，通知退出黑屏模式
                while (true)
                {
                    Logger.Singleton.Info($"开始轮询--{DateTime.Now.ToString("HH:mm:ss")}");
                    if (DataCommunicationMng.GetInstance().GetServerRunFlag() == false)
                    {
                        break;
                    }


                    dataTable = null;

                    if (bServerChange)
                    {
                        bServerChange = false;
                        userAccess = 0;
                        currentServerUse = currentServerUse + 1 > 1 ? currentServerUse = 0 : currentServerUse++;
                    }

                    SqlHelper eventServer = eventServerArray[currentServerUse];


                    //if (isFirstInit)
                    //{
                    //    Logger.Singleton.Info($"开始初始化--{DateTime.Now.ToString("HH:mm:ss")}");
                    //    try
                    //    {
                    //        string userAccessSql = "SELECT TOP (1) [name],[user_access] FROM [emsevents].[sys].[databases] where [name] ='QBDB'";
                    //        DataTable dtUserAccess = eventServerArray[currentServerUse].GetByTable(userAccessSql);
                    //        if (dtUserAccess != null && dtUserAccess.Rows.Count > 0)
                    //        {
                    //            userAccess = Convert.ToInt32(dtUserAccess.Rows[0]["user_access"]);
                    //        }
                    //      //  initGroupScreenInfos(TagGroups, eventServer);
                    //        isFirstInit = false;
                    //        continue;
                    //    }
                    //    catch(Exception e)
                    //    {
                    //        ErroInfo("主从切换1", e, null);
                    //        bServerChange = true;
                    //        Thread.Sleep(2000);
                    //        continue;
                    //    }
                    //}

                    try
                    {
                        string userAccessSql = "SELECT TOP(1) [name],[user_access] FROM [emsevents].[sys].[databases] where [name] ='QBDB'";
                        DataTable dtUserAccess = eventServerArray[currentServerUse].GetByTable(userAccessSql);
                        if (dtUserAccess != null && dtUserAccess.Rows.Count > 0)
                        {
                            if (userAccess != Convert.ToInt32(dtUserAccess.Rows[0]["user_access"]))
                            {
                                userAccess = Convert.ToInt32(dtUserAccess.Rows[0]["user_access"]);
                                Logger.Singleton.Info($"sys.database发现主从标志改变--{DateTime.Now.ToString("HH:mm:ss")}");
                                bServerChange = true;
                                Thread.Sleep(2000);
                                continue;
                            }
                        }
                        //判断客户端socket是否连接
                        DataCommunicationMng.GetInstance().CheckClientConnect();
                        Logger.Singleton.Info($"更新分组信息--{DateTime.Now.ToString("HH:mm:ss")}");
                        ModifyGroupInfos(eventServer, groupInfos, strSqlConditions);
                    }
                    catch (Exception ex)
                    {
                        NormalInfo("逻辑报错", ex, null);
                        //bServerChange = true;
                        Thread.Sleep(2000);
                        continue;
                    }

                    Thread.Sleep(parameters.frequency * 1000);
                }
            });
        }

        public string generateStr(List<string> tags, int splitNum, string fieldName)
        {
            int count = tags.Count;
            int splitGroup = count / splitNum + (count % splitNum == 0 ? 0 : 1);

            string str = string.Empty;
            str = $"{fieldName} in (";
            //拼凑成sql in语句
            for (int i = 0; i < splitGroup; i++)
            {
                for (int j = 0; j < splitNum; j++)
                {
                    if (i * splitNum + j < count)
                    {
                        str += "'" + tags[i * splitNum + j] + "',";
                    }
                }
                str = str.TrimEnd(',');
                if (i != splitGroup - 1)
                    str += $") or {fieldName} in (";
                else
                    str += ")";
            }
            return str;
        }
        private void initGroupScreenInfos(List<TagGroupModel> groupTags, SqlHelper sqlHelper)
        {
            foreach (TagGroupModel item in groupTags)
            {
                List<string> tags = item.TagList.Select(x => x.TagName).ToList();

                if (tags.Count == 0)
                {
                    continue;
                }
                //string tagStr = "";
                //int cntTags = tags.Count;
                //for (int i = 0; i < tags.Count; i++)
                //{
                //    if(i <800)
                //    {
                //        tagStr += $"'{tags[i]}',";
                //    }
                //}
                //foreach (var tag in item.TagList)
                //{
                //    tagStr += $"'{tag.TagName}',";
                //}
                //if (string.IsNullOrEmpty(tagStr))
                //{
                //    continue;
                //}
                //去掉最后一个逗号
                // tagStr = tagStr.Substring(0, tagStr.Length - 1);
                //查询距离当前最近的一次1，3报警信息。
                // string sqllatestAlarm = $"select top(1) [Action],[Source],[Category],[TransactionID],[LocalTime],[SourceSort],[AreaCode],[Priority],[ConditionName],[Block],[Description],[LocationTagName],[SourceEntityName],[Station] from [emsevents].[dbo].[Events] where Category in (1, 3) and [Source] in ({tagStr}) order by LocalTime desc";
                string sqllatestAlarm = $"select top(1) [Action],[Source],[Category],[TransactionID],[LocalTime],[SourceSort],[AreaCode],[Priority],[ConditionName],[Block],[Description],[LocationTagName],[SourceEntityName],[Station] from [emsevents].[dbo].[Events] where Category in (1, 3) and ({generateStr(tags, 800, "Source")}) order by LocalTime desc";
                Logger.Singleton.Info($"初始化分组信息--{sqllatestAlarm}");
                DataTable dt = sqlHelper.GetByTable(sqllatestAlarm);
                if (dt != null && dt.Rows.Count > 0)
                {
                    Int64 latestAlarmLocalTime = Convert.ToInt64(dt.Rows[0]["LocalTime"].ToString().Trim());
                    string latestAlarmConditionName = dt.Rows[0]["ConditionName"].ToString();
                    QueryEventValues queryEventValues = ConstructQueryEventValues(dt);
                    //有报警，查最近报警的ok事件
                    string sqlLatestOk = $"select top(1) [Action],[Source],[Category],[TransactionID],[LocalTime],[SourceSort],[AreaCode],[Priority],[ConditionName],[Block],[Description],[LocationTagName],[SourceEntityName],[Station] from [emsevents].[dbo].[Events] where  LocalTime > {ProjectTools.ConvertToPhdTime(queryEventValues.LocalTime)} " +
                        $"and  [TransactionID] = {queryEventValues.TransactionID} " +
                        $"and [ConditionName] ='{latestAlarmConditionName}'" +
                        $"and [LocalTime]>{latestAlarmLocalTime}" +
                        $"and Category in (1,3) and ({generateStr(tags, 800, "Source")})  and [Action]='OK'";
                    DataTable dtOk = sqlHelper.GetByTable(sqlLatestOk);
                    if (dtOk != null && dtOk.Rows.Count > 0)
                    {
                        //存在对应的ok事件，则取最新的一次1，3，7事件为基准事件
                        string sqlLatest = $"select top(1) [Action],[Source],[Category],[TransactionID],[LocalTime],[SourceSort],[AreaCode],[Priority],[ConditionName],[Block],[Description],[LocationTagName],[SourceEntityName],[Station] from [emsevents].[dbo].[Events] where Category in (1, 3, 7) and [Action]!='OK' and ({generateStr(tags, 800, "Source")}) order by LocalTime desc";
                        DataTable dtLatest = sqlHelper.GetByTable(sqlLatest);
                        if (dtLatest != null && dtLatest.Rows.Count > 0)
                        {
                            BlackScreenExtraInfo blackScreenExtraInfo = constructBlackScreenExtraInfo(dtLatest, item.GroupName);
                            QueryEventValues initGroupScreenInfo = ConstructQueryEventValues(dtLatest);
                            DataCommunicationMng.GetInstance().ModifyGroupScreenInfos(Convert.ToInt32(item.Id), initGroupScreenInfo, blackScreenExtraInfo);
                        }
                    }
                    else
                    {
                        //不存在对应的ok事件，查询对应报警是否存在报警确认事件
                        //1.若存在对应的报警确认事件，则取最新的一次报警确认事件为基准事件
                        //2.不存在对应的报警确认事件，则取最新的一次1，3，7事件为基准事件
                        BlackScreenExtraInfo blackScreenExtraInfo = constructBlackScreenExtraInfo(dt, item.GroupName);
                        QueryEventValues initGroupScreenInfo = ConstructQueryEventValues(dt);
                        DataCommunicationMng.GetInstance().ModifyGroupScreenInfos(Convert.ToInt32(item.Id), initGroupScreenInfo, blackScreenExtraInfo);
                    }

                }
                else
                {
                    //若没有报警事件(1,3)，则取过程报警事件为基准事件
                    string sqlLatest = $"select top(1) [Action],[Source],[Category],[TransactionID],[LocalTime],[SourceSort],[AreaCode],[Priority],[ConditionName],[Block],[Description],[LocationTagName],[SourceEntityName],[Station] from [emsevents].[dbo].[Events] where Category in (1, 3, 7) and [Action]!='OK' and ({generateStr(tags, 800, "Source")}) order by LocalTime desc";
                    DataTable dtLatest = sqlHelper.GetByTable(sqlLatest);
                    if (dtLatest != null && dtLatest.Rows.Count > 0)
                    {
                        BlackScreenExtraInfo blackScreenExtraInfo = constructBlackScreenExtraInfo(dtLatest, item.GroupName);
                        QueryEventValues initGroupScreenInfo = ConstructQueryEventValues(dtLatest);
                        DataCommunicationMng.GetInstance().ModifyGroupScreenInfos(Convert.ToInt32(item.Id), initGroupScreenInfo, blackScreenExtraInfo);
                    }
                }
            }
        }

        private List<TagGroupModel> GetTagGroupFromTable(DataTable dtGroup, DataTable dtBlackList)
        {
            List<TagGroupModel> gps = new List<TagGroupModel>();
            if (dtGroup != null && dtGroup.Rows.Count > 0)
            {
                for (int i = 0; i < dtGroup.Rows.Count; i++)
                {
                    TagGroupModel gp = new TagGroupModel();
                    gp.Id = (ulong)Convert.ToInt64(dtGroup.Rows[i]["id"]);
                    gp.GroupName = dtGroup.Rows[i]["Name"].ToString();
                    gp.TagList = GetTagFromTable(dtBlackList, gp.Id);
                    gps.Add(gp);
                }
            }
            return gps;
        }

        private List<TagModel> GetTagFromTable(DataTable dt, ulong groupId)
        {
            List<TagModel> tagModels = new List<TagModel>();
            if (dt != null && dt.Rows.Count > 0)
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    if (dt.Rows[i]["GroupId"] != null && (ulong)Convert.ToInt64(dt.Rows[i]["GroupId"]) == groupId)
                    {
                        TagModel tm = new TagModel();
                        tm.id = (ulong)Convert.ToInt64(dt.Rows[i]["TagId"]);
                        tm.GroupId = (ulong)Convert.ToInt64(dt.Rows[i]["GroupId"]);
                        tm.TagName = dt.Rows[i]["TagName"].ToString();
                        tm.GroupName = dt.Rows[i]["GroupName"].ToString();

                        tagModels.Add(tm);
                    }
                }
            }
            return tagModels;
        }

        //根据分组信息，黑白名单，创建sql条件拼接语句
        private Dictionary<int, string> GenConditionSqlPart(List<ListInfo> blacklist, List<ListInfo> whiteList, List<GroupInfo> groups)
        {
            Dictionary<int, string> result = new Dictionary<int, string>();
            foreach(var gp in groups)
            {
                //从黑名单中找到对应分组的信息
                List<ListInfo> gp_blacklist = blacklist.Where(x => x.GroupName.Trim() == gp.Name.Trim()).ToList();
                List<ListInfo> gp_whitelist = whiteList.Where(x => x.GroupName.Trim() == gp.Name.Trim()).ToList();
                List<string> blackConditions = new List<string>();
                foreach (var l in gp_blacklist)
                {
                    if (l.AreaName.Trim() == "*" && l.Category == 0 && l.EventType.Trim() == "*" && l.Block.Trim() == "*" && l.Source.Trim() == "*")
                        continue;
                    string condition = "(";
                    if (l.AreaName.Trim() != "*")
                    { 
                        if(l.AreaName.Trim().Contains('*'))
                            condition += $"[LocationTagName] like '{l.AreaName.Trim().Replace('*','%')}' and ";
                        else
                            condition += $"[LocationTagName] = '{l.AreaName}' and ";
                    }

                    if (l.Category != 0)
                        condition += $"[Category] = {l.Category} and ";
                    if (l.EventType.Trim() != "*")
                    {
                        if (l.EventType.Trim().Contains('*'))
                            condition += $"[ConditionName] like '{l.EventType.Trim().Replace('*', '%')}' and ";
                        else
                            condition += $"[ConditionName] = '{l.EventType}' and ";
                    }
                    if (l.Block.Trim() != "*")
                    {
                        if (l.Block.Trim().Contains('*'))
                            condition += $"[Block] like '{l.Block.Trim().Replace('*', '%')}' and ";
                        else
                            condition += $"[Block] = '{l.Block}' and ";
                    }

                    if (l.Source.Trim() != "*")
                    {
                        if(l.Source.Trim().Contains('*'))
                            condition += $"[Source] like '{l.Source.Trim().Replace('*', '%')}'";
                        else
                            condition += $"[Source] = '{l.Source}'";
                    }

                    //若最后4为字符串为"and ",去掉最后一个and
                    if (condition.Substring(condition.Length - 4, 4) == "and ")
                        condition = condition.Substring(0, condition.Length - 4);
                    condition += ")";

                    blackConditions.Add(condition);
                }

                List<string> whiteConditions = new List<string>();
                foreach (var l in gp_whitelist)
                {
                    if (l.AreaName.Trim() == "*" && l.Category == 0 && l.EventType.Trim() == "*" && l.Block.Trim() == "*" && l.Source.Trim() == "*")
                        continue;
                    string condition = "(";
                    if (l.AreaName.Trim() != "*")
                    {
                        if(l.AreaName.Trim().Contains('*'))
                        {
                            condition += $"[LocationTagName] not like '{l.AreaName.Replace('*','%')}' or [LocationTagName] is NULL or ";
                        }
                        else
                        {
                            condition += $"[LocationTagName] != '{l.AreaName}' or [LocationTagName] is NULL or ";
                        }
                    }
                       
                    if (l.Category != 0)
                        condition += $"[Category] != {l.Category} or [Category] is NULL or ";
                    if (l.EventType.Trim() != "*")
                    {
                        if(l.EventType.Trim().Contains('*'))
                            condition += $"[ConditionName] not like '{l.EventType.Trim().Replace('*', '%')}' or [ConditionName] is NULL or ";
                        else
                            condition += $"[ConditionName] != '{l.EventType}' or [ConditionName] is NULL or ";
                    }

                    if (l.Block.Trim() != "*")
                    {
                        if(l.Block.Trim().Contains('*'))
                            condition += $"[Block] not like '{l.Block.Trim().Replace('*', '%')}' or [Block] is NULL or ";
                        else
                            condition += $"[Block] != '{l.Block}' or [Block] is NULL or ";
                    }
                       
                    if (l.Source.Trim() != "*")
                    {
                        if(l.Source.Trim().Contains('*'))
                            condition += $"[Source] not like '{l.Source.Trim().Replace('*', '%')}' or [Source] is NULL";
                        else
                            condition += $"[Source] != '{l.Source}' or [Source] is NULL";
                    }

                    if (condition.Substring(condition.Length - 3, 3) == "or ")
                        condition = condition.Substring(0, condition.Length - 3);
                    condition += ")";
                    whiteConditions.Add(condition);
                   
                }
                string blackJoin = "";
                string whiteJoin = "";
                string groupCondition = "";

                if (blackConditions.Count > 0)
                    blackJoin = "(" + string.Join(" or ", blackConditions) + ")";
                if(whiteConditions.Count > 0)
                    whiteJoin = "(" + string.Join(" and ", whiteConditions) + ")";
                
                if(blackJoin != "" && whiteJoin != "")
                   groupCondition = blackJoin + " and " + whiteJoin;
                else if (blackJoin != "")
                    groupCondition = blackJoin;
                else if (whiteJoin != "")
                    groupCondition = whiteJoin;
             
                result.Add(gp.Id, groupCondition);
            }
            return result;
        }

        private void ModifyGroupInfos(SqlHelper sqlHelper, List<GroupInfo> groups, Dictionary<int, string> conditions)
        {
            Logger.Singleton.Info($"进入参数更改--{DateTime.Now.ToString("HH:mm:ss")}");
            foreach (GroupInfo item in groups)
            {
                //获取分组的所有tag
                //List<string> tags = item.TagList.Select(x => x.TagName).ToList();
                //string tagStr = "";
                //foreach (var tag in item.TagList)
                //{
                //    tagStr += $"'{tag.TagName}',";
                //}
                //if (string.IsNullOrEmpty(tagStr))
                //{
                //    Logger.Singleton.Info($"无监测点位，刷新--{item.Id}--{DateTime.Now.ToString("HH:mm:ss")}");
                //    DataCommunicationMng.GetInstance().RefreshGroupScreenInfos(Convert.ToInt32(item.Id));
                //    continue;
                //}
                ////去掉最后一个逗号
                //tagStr = tagStr.Substring(0, tagStr.Length - 1);
                bool isAlarm = false;
                //获取最新一次的报警信息
                DateTime lastAlarmTime = DataCommunicationMng.GetInstance().GetGroupScreenInfos(Convert.ToInt32(item.Id)).QueryEventValues.LocalTime;
                Logger.Singleton.Info($"最新查询时间：{lastAlarmTime.ToString("yyyy-MM-dd HH:mm:ss")}");
                ulong ulLastAlarmTime = Convert.ToUInt64(ProjectTools.ConvertToPhdTime(lastAlarmTime));
                //string sql = $"select [Action],[Source],[Category],[TransactionID],[LocalTime],[SourceSort],[AreaCode],[Priority],[ConditionName],[Block],[Description],[LocationTagName],[SourceEntityName],[Station] from [emsevents].[dbo].[Events] " +
                //    $"where Category in (1, 3, 7) and [Action]!='OK' and [Source] in ({tagStr}) and LocalTime > {ulLastAlarmTime} order by LocalTime desc";
                string condition = conditions[item.Id] == "" ? "1 = 1" : conditions[item.Id];
                string sql = $"select [Action],[Source],[Category],[TransactionID],[LocalTime],[SourceSort],[AreaCode],[Priority],[ConditionName],[Block],[Description],[LocationTagName],[SourceEntityName],[Station] from [emsevents].[dbo].[Events] " +
                   $"where {condition} and ([Action]!='OK' or [Action] is NULL) and LocalTime > {ulLastAlarmTime} order by LocalTime asc";
                Logger.Singleton.Info($"查询事件记录sql:{sql}");
                DataTable dt = sqlHelper.GetByTable(sql);
                if (dt != null && dt.Rows.Count > 0)
                {
                    Logger.Singleton.Info($"查询事件记录结果条数:{dt.Rows.Count}");
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        QueryEventValues eventsValue = ConstructQueryEventValues(dt, i);

                        isAlarm = true;
                        Logger.Singleton.Info($"构造黑屏消息对象：{item.Name}----{i}");
                        BlackScreenExtraInfo blackExtraInfo = constructBlackScreenExtraInfo(dt, item.Name, i);
                        Logger.Singleton.Info($"更新报警--{item.Id}--{DateTime.Now.ToString("HH:mm:ss")}--sql:{sql}");
                        Logger.Singleton.Info($"更新报警--{item.Id}--{DateTime.Now.ToString("HH:mm:ss")}--alarm:{eventsValue.Source}-{eventsValue.Action}-{ulLastAlarmTime}");
                        DataCommunicationMng.GetInstance().ModifyGroupScreenInfos(Convert.ToInt32(item.Id), eventsValue, blackExtraInfo);
                    }
                 
                    
                }

                if (!isAlarm)
                {
                    Logger.Singleton.Info($"无报警，刷新--{item.Id}--{DateTime.Now.ToString("HH:mm:ss")}");
                    DataCommunicationMng.GetInstance().RefreshGroupScreenInfos(Convert.ToInt32(item.Id));
                }

            }
        }


        //private QueryEventValues ConstructQueryEventValues(DataTable dt, int row = 0)
        //{
        //    QueryEventValues queryEventValues = new QueryEventValues();
        //    if (dt != null && dt.Rows.Count > 0)
        //    {

        //        queryEventValues.Action = dt.Rows[row]["Action"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象Action：{queryEventValues.Action}");
        //        queryEventValues.Source = dt.Rows[row]["Source"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象Source：{queryEventValues.Source}");
        //        queryEventValues.Category = Convert.ToInt32(dt.Rows[row]["Category"].ToString().Trim());
        //        Logger.Singleton.Info($"构造黑屏消息对象Category：{queryEventValues.Category}");
        //        queryEventValues.TransactionID = Convert.ToInt64(dt.Rows[row]["TransactionID"].ToString().Trim());
        //        Logger.Singleton.Info($"构造黑屏消息对象TransactionID：{queryEventValues.TransactionID}");
        //        DateTime time = new DateTime();
        //        if (ProjectTools.ConvertActiveTime(dt.Rows[row]["LocalTime"].ToString().Trim(), out time))
        //        {
        //            queryEventValues.LocalTime = time;
        //            Logger.Singleton.Info($"构造黑屏消息对象time：{queryEventValues.LocalTime.ToString("yyyy-MM-dd HH:mm:ss")}");
        //        }
        //        queryEventValues.SourceSort = dt.Rows[row]["SourceSort"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象SourceSort：{queryEventValues.SourceSort}");
        //        queryEventValues.AreaCode = Convert.ToInt32(dt.Rows[row]["AreaCode"].ToString().Trim());
        //        Logger.Singleton.Info($"构造黑屏消息对象AreaCode：{queryEventValues.AreaCode}");
        //        queryEventValues.Priority = Convert.ToInt32(dt.Rows[row]["Priority"].ToString().Trim());
        //        Logger.Singleton.Info($"构造黑屏消息对象Priority：{queryEventValues.Priority}");
        //        queryEventValues.ConditionName = dt.Rows[row]["ConditionName"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象ConditionName：{queryEventValues.ConditionName}");
        //        queryEventValues.Block = dt.Rows[row]["Block"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象Block：{queryEventValues.Block}");
        //        queryEventValues.Description = dt.Rows[row]["Description"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象Description：{queryEventValues.Description}");
        //        queryEventValues.LocationTagName = dt.Rows[row]["LocationTagName"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象LocationTagName：{queryEventValues.LocationTagName}");
        //        queryEventValues.SourceEntityName = dt.Rows[row]["SourceEntityName"].ToString().Trim();
        //        Logger.Singleton.Info($"构造黑屏消息对象SourceEntityName：{queryEventValues.SourceEntityName}");
        //    }
        //    return queryEventValues;
        //}

        private QueryEventValues ConstructQueryEventValues(DataTable dt, int row = 0)
        {
            QueryEventValues queryEventValues = new QueryEventValues();

            if (dt == null || dt.Rows.Count <= 0 || row >= dt.Rows.Count)
                return queryEventValues;

            var dataRow = dt.Rows[row];

            // 辅助方法：安全获取字符串
            string GetString(string columnName)
            {
                var value = dataRow[columnName];
                return value == null || value == DBNull.Value ? string.Empty : value.ToString().Trim();
            }

            // 辅助方法：安全转换为 int
            bool TryGetInt(string columnName, out int result)
            {
                result = default;
                var str = GetString(columnName);
                return !string.IsNullOrEmpty(str) && int.TryParse(str, out result);
            }

            // 辅助方法：安全转换为 long
            bool TryGetLong(string columnName, out long result)
            {
                result = default;
                var str = GetString(columnName);
                return !string.IsNullOrEmpty(str) && long.TryParse(str, out result);
            }

            // Action
            queryEventValues.Action = GetString("Action");
            Logger.Singleton.Info($"构造黑屏消息对象Action：{queryEventValues.Action}");

            // Source
            queryEventValues.Source = GetString("Source");
            Logger.Singleton.Info($"构造黑屏消息对象Source：{queryEventValues.Source}");

            // Category
            if (TryGetInt("Category", out int category))
            {
                queryEventValues.Category = category;
            }
            Logger.Singleton.Info($"构造黑屏消息对象Category：{queryEventValues.Category}");

            // TransactionID
            if (TryGetLong("TransactionID", out long transactionId))
            {
                queryEventValues.TransactionID = transactionId;
            }
            Logger.Singleton.Info($"构造黑屏消息对象TransactionID：{queryEventValues.TransactionID}");

            // LocalTime
            var localTimeStr = GetString("LocalTime");
            if (!string.IsNullOrEmpty(localTimeStr) && ProjectTools.ConvertActiveTime(localTimeStr, out DateTime time))
            {
                queryEventValues.LocalTime = time;
                Logger.Singleton.Info($"构造黑屏消息对象time：{queryEventValues.LocalTime:yyyy-MM-dd HH:mm:ss}");
            }

            // SourceSort
            queryEventValues.SourceSort = GetString("SourceSort");
            Logger.Singleton.Info($"构造黑屏消息对象SourceSort：{queryEventValues.SourceSort}");

            // AreaCode
            if (TryGetInt("AreaCode", out int areaCode))
            {
                queryEventValues.AreaCode = areaCode;
            }
            Logger.Singleton.Info($"构造黑屏消息对象AreaCode：{queryEventValues.AreaCode}");

            // Priority
            if (TryGetInt("Priority", out int priority))
            {
                queryEventValues.Priority = priority;
            }
            Logger.Singleton.Info($"构造黑屏消息对象Priority：{queryEventValues.Priority}");

            // ConditionName
            queryEventValues.ConditionName = GetString("ConditionName");
            Logger.Singleton.Info($"构造黑屏消息对象ConditionName：{queryEventValues.ConditionName}");

            // Block
            queryEventValues.Block = GetString("Block");
            Logger.Singleton.Info($"构造黑屏消息对象Block：{queryEventValues.Block}");

            // Description
            queryEventValues.Description = GetString("Description");
            Logger.Singleton.Info($"构造黑屏消息对象Description：{queryEventValues.Description}");

            // LocationTagName
            queryEventValues.LocationTagName = GetString("LocationTagName");
            Logger.Singleton.Info($"构造黑屏消息对象LocationTagName：{queryEventValues.LocationTagName}");

            // SourceEntityName
            queryEventValues.SourceEntityName = GetString("SourceEntityName");
            Logger.Singleton.Info($"构造黑屏消息对象SourceEntityName：{queryEventValues.SourceEntityName}");

            return queryEventValues;
        }

        //private BlackScreenExtraInfo constructBlackScreenExtraInfo(DataTable dt, string groupName, int row = 0)
        //{
        //    Logger.Singleton.Info($"进入方法：constructBlackScreenExtraInfo");
        //    BlackScreenExtraInfo blackScreenExtraInfo = new BlackScreenExtraInfo();
        //    if (dt != null && dt.Rows.Count > 0)
        //    {
        //        blackScreenExtraInfo.source_sort = dt.Rows[row]["SourceSort"].ToString().Trim();
        //        Logger.Singleton.Info($"进入1");
        //        blackScreenExtraInfo.source = dt.Rows[row]["Source"].ToString().Trim();
        //        Logger.Singleton.Info($"进入2");
        //        blackScreenExtraInfo.Category = dt.Rows[row]["Category"].ToString().Trim();
        //        Logger.Singleton.Info($"进入3");
        //        blackScreenExtraInfo.area_code = Convert.ToInt32(dt.Rows[row]["AreaCode"].ToString().Trim());
        //        Logger.Singleton.Info($"进入4");
        //        int nPriority = Convert.ToInt32(dt.Rows[row]["Priority"].ToString().Trim());
        //        Logger.Singleton.Info($"进入5：{nPriority}");
        //        blackScreenExtraInfo.priority = ConvertPriority(nPriority);
        //        Logger.Singleton.Info($"进入6:{blackScreenExtraInfo.priority}");
        //        blackScreenExtraInfo.condition_name = dt.Rows[row]["ConditionName"].ToString().Trim();
        //        Logger.Singleton.Info($"进入7:{blackScreenExtraInfo.condition_name}");
        //        blackScreenExtraInfo.block = dt.Rows[row]["Block"].ToString();
        //        Logger.Singleton.Info($"进入8:{blackScreenExtraInfo.block}");
        //        blackScreenExtraInfo.description = dt.Rows[row]["Description"].ToString();
        //        Logger.Singleton.Info($"进入9:{blackScreenExtraInfo.description}");
        //        blackScreenExtraInfo.groupName = groupName;
        //        Logger.Singleton.Info($"进入10:{blackScreenExtraInfo.groupName}");
        //        blackScreenExtraInfo.station = dt.Rows[row]["Station"].ToString().Trim();
        //        Logger.Singleton.Info($"进入11:{blackScreenExtraInfo.station}");
        //        blackScreenExtraInfo.location_tag_name = dt.Rows[row]["LocationTagName"].ToString().Trim();
        //        Logger.Singleton.Info($"进入12:{blackScreenExtraInfo.location_tag_name}");
        //        int category = Convert.ToInt32(dt.Rows[row]["Category"].ToString().Trim());
        //        if (dicCategoryDesc.ContainsKey(category))
        //            blackScreenExtraInfo.category_name = dicCategoryDesc[category];
        //        else
        //            blackScreenExtraInfo.category_name = "未知";
        //        Logger.Singleton.Info($"进入13:{blackScreenExtraInfo.category_name}");
        //    }
        //    return blackScreenExtraInfo;
        //}

        private BlackScreenExtraInfo constructBlackScreenExtraInfo(DataTable dt, string groupName, int row = 0)
        {
            Logger.Singleton.Info($"进入方法：constructBlackScreenExtraInfo");
            BlackScreenExtraInfo blackScreenExtraInfo = new BlackScreenExtraInfo();

            if (dt == null || dt.Rows.Count <= 0 || row >= dt.Rows.Count)
            {
                Logger.Singleton.Warn("DataTable 为空、无行数据或指定行索引超出范围。返回默认 BlackScreenExtraInfo。");
                blackScreenExtraInfo.groupName = groupName; // 保留 groupName
                return blackScreenExtraInfo;
            }

            var dataRow = dt.Rows[row];

            // 安全获取字符串字段（处理 DBNull 和 null）
            string GetSafeString(string columnName)
            {
                var val = dataRow[columnName];
                return val == DBNull.Value || val == null ? string.Empty : val.ToString().Trim();
            }

            // 安全转换整数（处理 DBNull、null、非数字）
            int GetSafeInt(string columnName, int defaultValue = 0)
            {
                var val = dataRow[columnName];
                if (val == DBNull.Value || val == null) return defaultValue;
                if (int.TryParse(val.ToString(), out int result))
                    return result;
                Logger.Singleton.Warn($"无法解析整数字段 {columnName}，值为 '{val}'，使用默认值 {defaultValue}");
                return defaultValue;
            }

            try
            {
                blackScreenExtraInfo.source_sort = GetSafeString("SourceSort");
                Logger.Singleton.Info($"进入1: source_sort={blackScreenExtraInfo.source_sort}");

                blackScreenExtraInfo.source = GetSafeString("Source");
                Logger.Singleton.Info($"进入2: source={blackScreenExtraInfo.source}");

                blackScreenExtraInfo.Category = GetSafeString("Category");
                Logger.Singleton.Info($"进入3: Category={blackScreenExtraInfo.Category}");

                blackScreenExtraInfo.area_code = GetSafeInt("AreaCode");
                Logger.Singleton.Info($"进入4: area_code={blackScreenExtraInfo.area_code}");

                int nPriority = GetSafeInt("Priority");
                Logger.Singleton.Info($"进入5：nPriority={nPriority}");

                blackScreenExtraInfo.priority = ConvertPriority(nPriority);
                Logger.Singleton.Info($"进入6: priority={blackScreenExtraInfo.priority}");

                blackScreenExtraInfo.condition_name = GetSafeString("ConditionName");
                Logger.Singleton.Info($"进入7: condition_name={blackScreenExtraInfo.condition_name}");

                blackScreenExtraInfo.block = GetSafeString("Block");
                Logger.Singleton.Info($"进入8: block={blackScreenExtraInfo.block}");

                blackScreenExtraInfo.description = GetSafeString("Description");
                Logger.Singleton.Info($"进入9: description={blackScreenExtraInfo.description}");

                blackScreenExtraInfo.groupName = groupName;
                Logger.Singleton.Info($"进入10: groupName={blackScreenExtraInfo.groupName}");

                blackScreenExtraInfo.station = GetSafeString("Station");
                Logger.Singleton.Info($"进入11: station={blackScreenExtraInfo.station}");

                blackScreenExtraInfo.location_tag_name = GetSafeString("LocationTagName");
                Logger.Singleton.Info($"进入12: location_tag_name={blackScreenExtraInfo.location_tag_name}");

                // 注意：这里 "Category" 字段之前被当作字符串，现在又要转 int？
                // 如果数据库中 Category 是字符串（如 "1"），这里可以尝试解析；否则需确认字段类型一致性
                int category = GetSafeInt("Category", -1); // 使用 -1 作为无效标识
                if (category >= 0 && dicCategoryDesc.ContainsKey(category))
                {
                    blackScreenExtraInfo.category_name = dicCategoryDesc[category];
                }
                else
                {
                    blackScreenExtraInfo.category_name = "未知";
                    if (category != -1)
                    {
                        Logger.Singleton.Warn($"Category 值 {category} 不在 dicCategoryDesc 中");
                    }
                }
                Logger.Singleton.Info($"进入13: category_name={blackScreenExtraInfo.category_name}");
            }
            catch (Exception ex)
            {
                Logger.Singleton.Error($"constructBlackScreenExtraInfo 发生异常: {ex.Message}", ex);
                // 可选择抛出异常或返回部分填充的对象
                blackScreenExtraInfo.groupName = groupName; // 至少保留 groupName
            }

            return blackScreenExtraInfo;
        }

        private string ConvertPriority(int priority)
        {
            byte low = Convert.ToByte(priority & 0x0F);
            byte high = Convert.ToByte((priority & 0xF0) >> 4);

            string strHigh = string.Empty;
            string strLow = string.Empty;

            switch (high)
            {
                case 1:
                    strHigh = "L";
                    break;
                case 2:
                    strHigh = "H";
                    break;
                case 3:
                    strHigh = "U";
                    break;
                case 6:
                    strHigh = "J";
                    break;

                default:
                    strHigh = "";
                    break;
            }
            //将low转为2位数字字符串，不足2位前面补0
            strLow = low.ToString("D2");
            return strHigh + strLow;
        }
        public bool ValidateData()
        {
            string localDbConStr = ProjectTools.configDbConnString;
            string eventDbConStr1 = ProjectTools.eventDbConnectionModel.Conn1;
            string eventDbConStr2 = ProjectTools.eventDbConnectionModel.Conn2;
            string tcpServerIp = ProjectTools.getTcpServer().IpAddress;
            string tcpServerPort = ProjectTools.getTcpServer().PortNumber.ToString();
            string frequency = ProjectTools.getParamInfos().frequency.ToString();
            string interval = ProjectTools.getParamInfos().interval.ToString();
            string ignore = ProjectTools.getParamInfos().ignore.ToString();
            string file_local = ProjectTools.getParamInfos().file_location_local;
            string file_net = ProjectTools.getParamInfos().file_location_net;

            if (string.IsNullOrEmpty(localDbConStr.Trim()))
            {
                System.Windows.MessageBox.Show("请设置本地数据库配置！", "提示");
                return false;
            }

            if (string.IsNullOrEmpty(eventDbConStr1.Trim()) && string.IsNullOrEmpty(eventDbConStr2.Trim()))
            {
                System.Windows.MessageBox.Show("请设置主从服务器的配置！", "提示");
                return false;
            }

            if (string.IsNullOrEmpty(tcpServerIp.Trim()) || string.IsNullOrEmpty(tcpServerPort.Trim()))
            {
                System.Windows.MessageBox.Show("请设置TCP服务器的IP地址和端口号！", "提示");
                return false;
            }

            //判断输入的服务器IP地址是否合法
            if (!IPAddress.TryParse(tcpServerIp, out _))
            {
                System.Windows.MessageBox.Show("请设置正确的服务器IP！", "提示");
                return false;
            }

            if (!Int32.TryParse(tcpServerPort, out _))
            {
                System.Windows.MessageBox.Show("请设置正确的服务器端口号！", "提示");
                return false;
            }

            if (string.IsNullOrEmpty(frequency.Trim()))
            {
                System.Windows.MessageBox.Show("请设置数据库轮询频率！", "提示");
                return false;
            }

            if (!double.TryParse(frequency, out double frequencyValue))
            {
                System.Windows.MessageBox.Show("数据库轮询频率必须为数字！", "提示");
                return false;
            }

            if (string.IsNullOrEmpty(interval.Trim()))
            {
                System.Windows.MessageBox.Show("请设置定时报表的时间间隔！", "提示");
                return false;
            }

            if (!double.TryParse(interval, out double intervalValue))
            {
                System.Windows.MessageBox.Show("定时报表的时间间隔必须为数字！", "提示");
                return false;
            }

            if (string.IsNullOrEmpty(ignore.Trim()))
            {
                System.Windows.MessageBox.Show("请设置定时报表的忽略时间！", "提示");
                return false;
            }

            if (!double.TryParse(ignore, out double ignoreValue))
            {
                System.Windows.MessageBox.Show("定时报表的忽略时间必须为数字！", "提示");
                return false;
            }

            if (string.IsNullOrEmpty(file_local.Trim()))
            {
                System.Windows.MessageBox.Show("请设置本地文件路径！", "提示");
                return false;
            }

            if (string.IsNullOrEmpty(file_net.Trim()))
            {
                System.Windows.MessageBox.Show("请设置网络文件路径！", "提示");
                return false;
            }

            if (!Directory.Exists(file_local))
            {
                System.Windows.MessageBox.Show("请设置正确的本地文件夹！", "提示");
                return false;
            }

            if (!Directory.Exists(file_net))
            {
                System.Windows.MessageBox.Show("请设置正确的网络文件夹！", "提示");
                return false;
            }

            if (string.Equals(file_local, file_net))
            {
                System.Windows.MessageBox.Show("本地文件夹和网络文件夹位置不能相同，请重新设置！", "提示");
                return false;
            }
            return true;
        }

        private void btn_ServerStart(object sender, RoutedEventArgs e)
        {

            //验证启动所需数据是否存在
            if (ValidateData())
            {
                SetServerStatus(true);

                txtServerState.Text = "服务已启动";
                this.btnServerStart.IsChecked = true;
            }
            else
            {
                this.btnServerStart.IsChecked = false;
            }



            //TimedFormPage timedFormPage = new TimedFormPage();
            //ParametesSetupPage parametesSetupPage = new ParametesSetupPage();
            //MonitoringPage monitoringPage = new MonitoringPage();
            //DatabasePage databasePage = new DatabasePage();

            //timedFormPage.txtInterval.IsReadOnly = true;
            //parametesSetupPage.txtDelayTime.IsReadOnly = true;
            //parametesSetupPage.txtIgnore.IsReadOnly = true;
            //monitoringPage.btnGroupSetting.IsEnabled = false;
            //monitoringPage.btnImportWhiteList.IsEnabled = false;
            //databasePage.btnAddServer.IsEnabled = false;
            //databasePage.txtFrequency.IsReadOnly = true;
            //databasePage.txtHostName.IsReadOnly = true;
            //databasePage.txtPort.IsReadOnly = true;
        }


        private void btn_ServerStop(object sender, RoutedEventArgs e)
        {
            SetServerStatus(false);
            txtServerState.Text = "服务未启动";

            //timedFormPage.txtInterval.IsReadOnly = false;
            //parametesSetupPage.txtDelayTime.IsReadOnly = false;
            //parametesSetupPage.txtIgnore.IsReadOnly = false;
            //monitoringPage.btnGroupSetting.IsEnabled = true;
            //monitoringPage.btnImportWhiteList.IsEnabled = true;
            //databasePage.btnAddServer.IsEnabled = true;
            //databasePage.txtFrequency.IsReadOnly = false;
            //databasePage.txtHostName.IsReadOnly = false;
            //databasePage.txtPort.IsReadOnly = false;

        }
    }
}
